package com.education.wisdom.controller.wxpay;

import com.education.common.config.WebSocketServer;
import com.education.common.pojo.SysUserOther;
import com.education.common.utils.LogUtil;
import com.education.common.utils.UUIDUtils;
import com.education.wisdom.controller.wxpay.vo.WxVO;
import com.education.wisdom.feign.UserFeign;
import com.education.wisdom.pojo.CurrencyRecord;
import com.education.wisdom.pojo.Message;
import com.education.wisdom.pojo.PaymentRecord;
import com.education.wisdom.service.*;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.education.common.core.BaseController.writeJSON;

/**
 * 微信支付-扫码支付.
 * <p>
 * detailed description
 *
 * @author Mengday Zhang
 * @version 1.0
 * @since 2018/6/18
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/wxpay/precreate")
public class WXPayPrecreateController {
    @Autowired
    private WXPay wxPay;

    @Autowired
    private WXPayClient wxPayClient;

    @Autowired
    private IPaymentRecordService paymentRecordService;

    @Autowired
    private ISysAppLoginService sysAppLoginService;

    @Autowired
    private IUserAccountService accountService;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private ICurrencyRecordService currencyRecordService;

    @Autowired
    private MessageService messageService;


    /**
     * 扫码支付 - 统一下单
     * 相当于支付不的电脑网站支付
     *
     * <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1">扫码支付API</a>
     */
    @GetMapping("")
    public ModelAndView precreate1(String userId, Double amount) {
        log.info(LogUtil.LogInfo("微信支付获取订单号", new Date()));
        ModelAndView mv = new ModelAndView("redirect:http://www.jinruancloud.com/view/wxpay.html");
        Map<String, Object> login = userFeign.selectByUserId(Integer.parseInt(userId));
        if (login != null) {
            Object name = login.get("name");

            String out_trade_no = String.valueOf(System.nanoTime());
            mv.addObject("out_trade_no", out_trade_no);
            mv.addObject("userId", userId);
            mv.addObject("amount", amount);

            BigDecimal bl = new BigDecimal(amount);
            PaymentRecord record = new PaymentRecord();
            record.setRecordId(out_trade_no);
            record.setCreateTime(new Date());
            record.setUserId(userId);
            record.setPayerName(name.toString());
            record.setPayerUserNo(userId);
            record.setPayWayName("微信");
            record.setTrxType("2");
            record.setPayerPayAmount(bl);
            record.setOrderAmount(bl);
            paymentRecordService.insertPaymentRecord(record);
        }
        return mv;
    }

    @PostMapping("/pay")
    public void precreate(HttpServletRequest request, HttpServletResponse response, @RequestBody WxVO wxVO) throws Exception {
        log.info(LogUtil.LogInfo("微信支付获取二维码", new Date()));
//        SysAppLogin login = sysAppLoginService.selectSysAppLoginById(userId);
        Map<String, Object> login = userFeign.selectByUserId(Integer.parseInt(wxVO.getUserId()));
        if (login != null) {
            Map<String, String> reqData = new HashMap<>();
            String uuId = UUIDUtils.getByUUId();
            reqData.put("out_trade_no", uuId);
            reqData.put("trade_type", "NATIVE");
            reqData.put("product_id", "1");
            reqData.put("body", "商户下单");
//            String expireTime=getOrderExpireTime(30*60*100L);
//            reqData.put("time_expire", expireTime);
//            amount =amount * 100;
            Integer cmoney = new BigDecimal(String.valueOf(wxVO.getAmount())).movePointRight(2).intValue();
            // 订单总金额，单位为分
            reqData.put("total_fee", String.valueOf(cmoney));
            // APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
            reqData.put("spbill_create_ip", "192.168.0.138");
            //异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
            reqData.put("notify_url", "http://192.168.0.138:10010/api/wisdom/wxpay/precreate/notify");
            // 自定义参数, 可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
            reqData.put("device_info", "");
            //  附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
            reqData.put("attach", "");
            Map<String, String> responseMap = wxPay.unifiedOrder(reqData);
            log.info(responseMap.toString());
            String returnCode = responseMap.get("return_code");
            String resultCode = responseMap.get("result_code");
            if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
                String prepayId = responseMap.get("prepay_id");
                String codeUrl = responseMap.get("code_url");

//                //添加支付记录
//                CurrencyRecord record = new CurrencyRecord();
//                record.setCurrencyId(uuId);//订单号
//                record.setCreateTime(new Date());//创建时间
//                record.setStatus("2");//支付状态 1成功  0 支付失败 2 支付中
//                record.setUserId(wxVO.getUserId());//创建id
//                record.setPayerName(login.get("name").toString());//创建人名称
//
//                BigDecimal decimal = new BigDecimal(wxVO.getAmount());
//                BigDecimal de = new BigDecimal(10);
//                String substring = decimal.multiply(de).toString().substring(0, 1);
//                record.setCurrency(Integer.parseInt(substring));//支付金额
//                record.setRemark("用户微信充值");//充值类型
//                currencyRecordService.insertCurrencyRecord(record);

                BufferedImage image = PayUtil.getQRCodeImge(codeUrl);
                QRCodeUtil qrCodeUtil = new QRCodeUtil();
                String qrCode = qrCodeUtil.createQRCode(codeUrl, 300, 300);
                response.setContentType("image/jpeg");
                response.setHeader("Pragma", "no-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setIntHeader("Expires", -1);
//                ImageIO.write(qrCode, "JPEG", response.getOutputStream());
                writeJSON(qrCode, response, "200", "success");
            }
        }
    }

    /**
     * @param request
     * @return
     * @throws Exception
     */
//    @GetMapping("/notify")
    @RequestMapping("/notify")
    public String precreateNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, String> reqData = wxPayClient.getNotifyParameter(request);

        log.info(reqData.toString());

        // 特别提醒：商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致，防止数据泄漏导致出现“假通知”，造成资金损失。
        boolean signatureValid = wxPay.isPayResultNotifySignatureValid(reqData);
        if (signatureValid) {
            /**
             * 注意：同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
             * 推荐的做法是，当收到通知进行处理时，首先检查对应业务数据的状态，
             * 判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。
             * 在对业务数据进行状态检查和处理之前，要采用数据锁进行并发控制，以避免函数重入造成的数据混乱。
             */

            Map<String, String> responseMap = new HashMap<>(2);
            responseMap.put("return_code", "SUCCESS");
            responseMap.put("return_msg", "OK");
            String responseXml = WXPayUtil.mapToXml(responseMap);

            String out_trade_no = reqData.get("out_trade_no");
            String transaction_id = reqData.get("transaction_id");

            //根据交易订单号查询交易信息
            CurrencyRecord currencyRecord = currencyRecordService.selectByCurrencyId(out_trade_no);


            //修改交易状态为支付成功
            CurrencyRecord record = new CurrencyRecord();
            record.setCurrencyId(out_trade_no);//订单号
            record.setStatus("1");//支付状态 1成功  0 支付失败 2 支付中
            record.setEditTime(new Date());//修改时间
            currencyRecordService.updateCurrencyRecord(record);

            //修改用户达人币
            Map<String, Object> login = userFeign.selectByUserId(Integer.parseInt(currencyRecord.getUserId()));
            Map<String, Object> map = new HashMap<>();
            map.put("id", currencyRecord.getUserId());
            BigDecimal price = new BigDecimal(login.get("price").toString());
            int i = Integer.parseInt(currencyRecord.getCurrency().toString());
            //map.put("price", price + i);
            map.put("price", price.add(new BigDecimal(i)));
            //userFeign.updataByUserId(map);
            userFeign.updatePriceByUserId(Integer.parseInt(currencyRecord.getUserId()), price.add(new BigDecimal(i)));

            //添加充值信息
            Message message = new Message();
            message.setTitle("微信充值成功");
            message.setType("2");
            message.setCreatetime(new Date());
            message.setUserId(Integer.parseInt(currencyRecord.getUserId()));
            message.setIsRead("1");
            messageService.insertMessage(message);
            //查询消息推送
            Integer count = messageService.selectCount(currencyRecord.getUserId());
            try {
                WebSocketServer.sendInfo(count.toString(), currencyRecord.getUserId());
            } catch (IOException e) {
                e.printStackTrace();
            }


            return "redirect:http://192.168.0.134:8080/#/PaySuccess";

        } else {
            return "redirect:http://192.168.0.134:8080/#/PayError";
        }
    }

    @RequestMapping("/ajaxMonitor")
    public Map precreateNotify(String recordId) {
        Map map = new HashMap();
        PaymentRecord paymentRecord1 = paymentRecordService.selectPaymentRecordByrId(recordId);
        String a = paymentRecord1.getStatus();
        if (a.equals("1")) {
            map.put("success", "true");
        } else {
            map.put("success", "false");
        }
        return map;
    }


    @PostMapping("/getinfo")
    public Map precreategetinfo(String userId, Double amount) {
        Map map = new HashMap();
//        SysAppLogin login = sysAppLoginService.selectSysAppLoginById(userId);
        SysUserOther sysUserOther = userFeign.selectOnePCF(userId);
        if (sysUserOther != null) {
            String userName = sysUserOther.getSysRelname();

            String out_trade_no = String.valueOf(System.nanoTime());

            map.put("out_trade_no", out_trade_no);
            map.put("userId", userId);
            map.put("amount", amount);

            BigDecimal bl = new BigDecimal(amount);
            PaymentRecord record = new PaymentRecord();
            record.setRecordId(out_trade_no);
            record.setCreateTime(new Date());
            record.setUserId(userId);
            record.setPayerName(userName);
            record.setPayerUserNo(userId);
            record.setPayWayName("微信");
            record.setTrxType("2");
            record.setPayerPayAmount(bl);
            record.setOrderAmount(bl);
            paymentRecordService.insertPaymentRecord(record);
        }
        return map;
    }

    /**
     * 设置微信二维码失效时间，并返回具体失效的时间点
     *
     * @param expire 二维码的有效时间，单位是毫秒
     * @return
     */
    public static String getOrderExpireTime(Long expire) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Date now = new Date();
        Date afterDate = new Date(now.getTime() + expire);
        return sdf.format(afterDate);
    }
//    @GetMapping("/pay")
//    public Map precreate(HttpServletRequest request, HttpServletResponse response, String userId, int amount, String recordId) throws Exception {
//        Map map = new HashMap();
//        SysAppLogin login = sysAppLoginService.selectSysAppLoginById(userId);
//        if (login != null) {
//            Map<String, String> reqData = new HashMap<>();
//            reqData.put("out_trade_no", recordId);
//            reqData.put("trade_type", "NATIVE");
//            reqData.put("product_id", "1");
//            reqData.put("body", "商户下单");
//            amount = amount * 100;
//            // 订单总金额，单位为分
//            reqData.put("total_fee", amount + "");
//            // APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
//            reqData.put("spbill_create_ip", "14.23.150.211");
//            //异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
//            reqData.put("notify_url", "http://39.98.63.21:60/wxpay/precreate/notify");
//            // 自定义参数, 可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
//            reqData.put("device_info", "");
//            //  附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
//            reqData.put("attach", "");
//            map.put("out_trade_no", reqData.get("out_trade_no"));
//            map.put("userId", userId);
//            Map<String, String> responseMap = wxPay.unifiedOrder(reqData);
//            log.info(responseMap.toString());
//            String returnCode = responseMap.get("return_code");
//            String resultCode = responseMap.get("result_code");
//            if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
//                String prepayId = responseMap.get("prepay_id");
//                String codeUrl = responseMap.get("code_url");
//
//                BufferedImage image = PayUtil.getQRCodeImge(codeUrl);
//
//                response.setContentType("image/jpeg");
//                response.setHeader("Pragma", "no-cache");
//                response.setHeader("Cache-Control", "no-cache");
//                response.setIntHeader("Expires", -1);
//                ImageIO.write(image, "JPEG", response.getOutputStream());
//            }
//        }
//        return map;
//    }
//
}
